The Job Runner is a multi-threaded execution environment for VBScript and .NET assembly methods. Potential uses for Job Runner include:
Not every script is an ideal candidate for execution via the Job Runner. It uses a separate script engine and therefore does not have access to the shared objects in the HSS or CygNet Studio, such as the Facilities or Points objects (though you can create new instances of them). Ideal scripts are stand-alone and do not require outside input.
Errors are logged to a log file, named for the process where the Job Runner is running, which is found in the C:\Users\[user]\AppData\Local\CygNet\LogFiles\JobRunner\ folder. You can override the default location using the SetLoggingLocation method.
You can also capture the output of your scripted jobs by using VBScript’s Standard Output. Anything written using the Write() or Echo() functions will be logged in the Job Runner and can be read using the GetJobOutput method.
See the following subsections for more information:
The JobRunner object and one of the following objects are necessary to execute a job:
The first step in executing a Job is to create a JobRunner object.
The following example creates a JobRunner object:
|
Dim g_objJobRunner
Set g_objJobRunner = CreateObject("CygNet.API.JobRunner.JobRunner") |
When creating the JobRunner object, be mindful of its scope as it can only execute jobs while it exists. The following script is an example of how NOT to create a JobRunner object. In the script below, when RunJob is called, it will create a JobRunner object, then execute its job. However, job execution does not block the script engine, so RunJob will exit along with all variables declared inside its scope, including the JobRunner object you created. If a single-thread hasn’t finished by then, the JobRunner object would be killed. This is why multi-threaded programming is preferable.
|
Sub RunJob()
Dim objJobRunner
Set objJobRunner = CreateObject("CygNet.API.JobRunner.JobRunner")
' create and execute Job …
End Sub |
Note: Best practice is to declare theJobRunner object in global scope for the script engine you are using. For CygNet Studio screens and HSS scripts, this is typically in the Declarations section.
Before executing any jobs, you can tell the JobRunner how many concurrent jobs you want it to run. There is no universally correct number of allowed threads; it depends on the computer that is running the jobs. This is done via the SetMaxActiveJobs method on the JobRunner object. In the following example, the script will limit the JobRunner to three concurrent threads. Once the limit has been reached, additional jobs will be queued and executed in the order submitted. The default number of active jobs for your Job Runner object is five.
|
g_objJobRunner.SetMaxActiveJobs 3 |
After creating a JobRunner object, either a Job object or a ScriptJob object must be created.
To execute a job using the Assembly method, create a Job object:
|
Dim objAssemblyJob
Set objAssemblyJob = CreateObject("CygNet.API.JobRunner.Job") |
Three pieces of information are necessary to locate the Assembly method that you want your job to run:
In the following example, the assembly name is CygNet.API.Reporter. In this assembly, the object (or class) is ReportEngine, which is written as CxAEReporter.ReportEngine. The method name on the ReportEngine object is CreateReport.
|
Set job = CreateObject("CygNet.API.JobRunner.Job")
job.AssemblyName = "CygNet.API.Reporter"
job.ClassName = "CxAEReporter.ReportEngine"
job.MethodName = "CreateReport" |
Note: The assembly used should be registered in the Windows Global Assembly Cache (GAC).
If you need to specify the parameters for the provided method, the Job object contains an array for this list of parameters. For example, the CreateReport method in the above example takes three parameters: the path to a Report Definition file, the HSS Site.Service, and whether a file should be saved. The following example shows how to set these parameters.
|
Dim arrParams (2)
arrParams (0) = "C:\Reports\report.rdf"
arrParams (1) = "CYGNET.HSS"
arrParams (2) = "true"
job.Parameters = arrParams |
Note: If the method invoked returns a string as a result, it will be stored in the Job Runner as the job’s status, which can be retrieved after the job is complete.
To execute a job using VBScript, use the ScriptJob object:
|
Dim objScriptJob
Set objScriptJob = CreateObject("CygNet.API.JobRunner.ScriptJob") |
A job’s script can come from multiple sources, as shown in the following table:
| Source | Description | ScriptSourceType Value | ScriptSourcePath Value |
|---|---|---|---|
|
Local script file |
The script to execute exists on a local file system, likely in a *.VBS file. |
0 |
Path to the local file (i.e., “C:\Scripts\MyScript.VBS”) |
|
CygNet (HSS) point |
The script to execute is specified in the Script section of an HSS point. This point’s script should NOT be enabled, because it will then be executed directly by the HSS, not by the Job Runner. |
1 |
Name of the HSS points (i.e., “CYGNET.HSS:JOBRUNNER_SCRIPT”) |
|
BSS script file |
The script to execute is in a file on the BSS. It will be copied locally and run. Note: See Configure Temporary Path for BSS Scripts to override the BSS path. |
2 |
Path to the BSS file (i.e., “CYGNET.BSS\SCRIPTS\MyScript.VBS”) |
For example, to configure a job to execute from an HSS point:
|
objScriptJob.ScriptSourceType = 1
objScriptJob.ScriptSourcePath = "CYGNET.HSS:JOBRUNNERTEST1_SCRIPT" |
Parameters for Script jobs are handled in the same way as Assembly jobs, except they are passed as command-line parameters to the script engine, rather than being passed into a method.
If, for example, you configure a script job with the parameters below:
|
Dim arrParams (2)
arrParams (0) = "CYGNET.UIS"
arrParams (1) = "ASH_WELL"
arrParams (2) = "142.42"
objScriptJob.Parameters = arrParams |
Then in the script that you execute, the parameter values can be accessed as in this example:
|
Set objCmdLineParameters = Wscript.Arguments |
The parameters will be listed in the new array in the same order that they were originally written. For example, objCmdLineParameters(0) will equal "CYGNET.UIS".
If the script fails, the error returned from the script engine is written to the Job Runner log file.
You can specify an alternate or temporary download location for BSS-based and point-based scripts:
|
g_objJobRunner.SetLoggingLocation "C:\CygNet\JobRunner\Logs", "JobRunnerOutput" |
Once both JobRunner and Job objects are created, you can submit the job to be run. The job will execute immediately unless the JobRunner already has its maximum number of threads running, in which case it will be queued until a thread is available.
To submit a job, use the ExecuteJob method on the JobRunner object:
|
g_objJobRunner.ExecuteJob(objScriptJob) |
Job status, such as job completion or error messages for failed operations, can be requested from the JobRunner by first storing the Job ID, and then using the GetJobStatus method.
To reference a job later, you must store its ID, which is returned from ExecuteJob. An example follows:
|
Dim nJobId
nJobId = g_objJobRunner.ExecuteJob(objScriptJob) |
Use GetJobStatus and include the Job ID to request status for the job:
|
Dim strStatus
strStatus = g_objJobRunner.GetJobStatus(nJobId) |
Use the following methods to retrieve other job information:
The following table lists and describes Status types that can be retrieved using JobRunner.
| Status | Description | Applicable Job Type |
|---|---|---|
|
Pending |
The Job Runner is processing the request to execute the job. |
All |
|
Queued |
The Job Runner is currently executing its maximum number of threads. The job will be run when a thread becomes available. |
All |
|
Running |
The job is currently active. |
All |
|
Script completed |
The script has finished successfully. |
Script job |
|
Script failed: <Error message> |
The script failed. More information provided in the error message. |
Script job |
|
Other |
If the method invoked in an Assembly job returns a string, it will be stored as the job's status. |
Assembly job |
A truncated status string can be stored to a CygNet point. This same status point can then be used for all jobs by setting the status point for the JobRunner. An example follows:
|
g_objJobRunner.SetStatusPoint("SITE.SERVICE:LONGPOINTID") |
Setting the StatusPoint property on the job sets a different status point per job:
|
Set job = CreateObject("CygNet.API.JobRunner.Job")
job.StatusPoint = "SITE.SERVICE:LONGPOINTID" |
Note: The status point must exist in CygNet before status can be written.
To request the output of a scripted job from the JobRunner, use the Write() or Echo() functions in VBScript to output messages. That data will be captured and logged with the associated Job ID. Once a script job is complete, use GetJobOutput to retrieve the messages written by the script.
To reference a job later, you must store its ID, which is returned from ExecuteJob. An example follows:
|
Dim nJobId
nJobId = g_objJobRunner.ExecuteJob(objScriptJob) |
Use GetJobOutput and include the Job ID to request the output of the job from the JobRunner:
|
Dim strOutput
strOutput = g_objJobRunner.GetJobOutput(nJobId) |
The GetJobError method can be used in the same way to request the errors associated with a job.
The following parameters are available on the ScriptJob level to allow you to select an output mode (synchronous or asynchronous) and whether to write output and errors to the log file:
| Parameter | Desciption | Default |
|---|---|---|
|
UseSynchronousOutput |
This parameter controls when the output of a scripted job will be available for retrieval via the GetJobOutput method.
|
True |
|
WriteOutputToLogFile |
This parameter controls whether the output is written to the log file. |
False |
|
WriteErrorToLogFile |
This parameter controls whether script errors are written to the log file. |
True |
These parameters are used in the following way:
|
Sub CreateJob(path, pathType)
Dim scriptJob
Set scriptJob = CreateObject("CygNet.API.JobRunner.ScriptJob") scriptJob.ScriptSourceType = pathType scriptJob.ScriptSourcePath = path
scriptJob.UseSynchronousOutput = True scriptJob.WriteOutputToLogFile = False scriptJob.WriteErrorToLogFile = True
Dim nJobId : nJobId = jobRunner.ExecuteJob(scriptJob)
End Sub |
Jobs can be scheduled using the same methods used to schedule other scripts in CygNet. The usual procedure is to schedule an MSS SetPoint task to run periodically. Then a HyperPoint is configured to monitor the same point that the MSS is changing. This is typically done in the OnInitializeEx event using the Points.AddPoint method and the NotifyHyperPoint parameter. When the MSS issues the SetPoint, the HyperPoint then triggers a script in the OnPointChange event to add a new job to the JobRunner. For more information, see Using HyperPoints.
In the OnPointChange event handler, you can create a job and pass it to the JobRunner that you created for the HSS. While this method appears similar to just writing a script in the HSS, once ExecuteJob is called, the HSS is able to continue on to the next HyperPoint script while your job script (or assembly method) runs in the background on a separate thread. This multi-threading capability is the true power of using Job Runner.
A sample HSS script using this method follows:
|
'(Declarations)
Dim g_objJobRunner Set g_objJobRunner = CreateObject("CygNet.API.JobRunner.JobRunner")
'End of (Declarations) Sub JOB_RUNNER_TEST_HSS_OnInitializeEx(This) Dim obj Set obj = CreateObject("CxScript.GlobalFunctions") obj.EnableLiveMode True Points.AddPoint "CYGDEMO.HSS:JOBRUNNERTEST_TRIGGER", This
End Sub
Sub JOB_RUNNER_TEST_HSS_OnPointChange(This, Tag) Dim value value = Points.Point(Tag).Value
This.Value = value
If value = "Go!" Then Dim obj Set obj = CreateObject("CxScript.GlobalFunctions") obj.EnableLiveMode True obj.SetPoint "CYGDEMO.HSS:JOBRUNNERTEST1_STATUS", "" obj.SetPoint "CYGDEMO.HSS:JOBRUNNERTEST2_STATUS", "" obj.SetPoint "CYGDEMO.HSS:JOBRUNNERTEST3_STATUS", ""
g_objJobRunner.SetMaxActiveJobs 3
Dim scriptJob1 Set scriptJob1 = CreateObject("CygNet.API.JobRunner.ScriptJob")
Dim scriptJob2 Set scriptJob2 = CreateObject("CygNet.API.JobRunner.ScriptJob")
Dim scriptJob3 Set scriptJob3 = CreateObject("CygNet.API.JobRunner.ScriptJob")
scriptJob1.ScriptSourceType = 1 scriptJob2.ScriptSourceType = 1 scriptJob3.ScriptSourceType = 1
scriptJob1.ScriptSourcePath = "CYGDEMO.HSS:JOBRUNNERTEST1_SCRIPT" scriptJob2.ScriptSourcePath = "CYGDEMO.HSS:JOBRUNNERTEST2_SCRIPT" scriptJob3.ScriptSourcePath = "CYGDEMO.HSS:JOBRUNNERTEST3_SCRIPT"
Dim scriptJobId1 Dim scriptJobId2 Dim scriptJobId3
scriptJobId1 = g_objJobRunner.ExecuteJob(scriptJob1) scriptJobId2 = g_objJobRunner.ExecuteJob(scriptJob2) scriptJobId3 = g_objJobRunner.ExecuteJob(scriptJob3)
obj.SetPoint Tag, "Stop!" End If End Sub |
To terminate any Job Runner script processes, use the KillAllScriptJobs() and KillScriptJob(int jobId) methods.
Note: The HSS may not restart successfully if a Job Runner script is still executing on the same port. To avoid this issue when the HSS shuts down, the scripter will need to make use of the OnTerminateEx event in conjunction with one of the new methods to either selectively terminate long-running scripts jobs or terminate all outstanding script jobs.
By default, the Job Runner writes logging and error information to a .csv file found in the C:\Users\[user]\AppData\Local\CygNet\LogFiles\JobRunner\ folder.
The name of the log file depends on the process where the Job Runner in running:
You can override this default location and file name using the SetLoggingLocation method. For example:
|
g_objJobRunner.SetLoggingLocation "C:\CygNet\JobRunner\Logs", "JobRunnerOutput" |
To greatly increase the amount of logging, use the EnableDebugLogging method for the Job Runner. Caution: this may greatly increase the amount of logging depending on the number of jobs and the frequency of execution. For example:
|
g_objJobRunner.EnableDebugLogging True |
For script jobs, VB Script’s Standard Output can also be used to capture the output of your scripted jobs. Anything written using the Write() or Echo() functions can be obtained from the Job Runner using the GetJobOutput method, described here.
Additionally, LogManager can be used to log to file.
A sample CygNet Studio screen called Job Runner Example.csf is located in the APPS Blob in the SCREXAMP folder. This screen allows you to create Assembly and Script jobs using some basic inputs for various required fields. It also displays a grid of jobs in the Job Runner along with their status. For scripted jobs, the grid also shows any output or errors. While this sample screen limits parameter input to three, there is no limit to the number of parameters that can be passed to a Job.
Troubleshooting a job running in the Job Runner can be complex as there are a number of moving parts. The following are recommendations for diagnosing issues.
If possible, test your script or .NET code separately from the Job Runner before moving into the Job Runner environment. The simpler the environment, the easier it is to find problems. If the code is script, use VbsEdit or a similar tool to ensure it works as expected. For .NET code, it is recommended that you use Visual Studio’s Unit Tests to test each method you plan on calling from the Job Runner.
All jobs in the Job Runner have a status that can be queried. Script jobs are limited to only returning errors from the script engine. However, in .NET assembly methods that return a string, the value is passed into the job’s status field and can be used to help understand where the job is failing.
Use verbose logging to increase the amount of logging detail to aid in troubleshooting. See Job Runner Logging above.
Because the HSS is single-threaded, to execute a long-running script without blocking the rest of your scripts, Job Runner should be used.
Some considerations before beginning:
Step 1: Create a Job Runner object for the entire HSS
When creating a Job Runner object, it must persist beyond the scope of a single procedure. If a Job Runner object goes out of scope, it will be deleted and all jobs it started will be killed. Even if the jobs have completed, their status will not be available if the Job Runner object is no longer running.
To create a Job Runner, declare it in the Declarations section of an HSS point. This will create the object in the global scope of the HSS. An example follows:
|
'(Declarations)
Dim g_objJobRunner
Set g_objJobRunner = CreateObject("CygNet.API.JobRunner.JobRunner")
'End of (Declarations) |
To limit the JobRunner to run only three jobs at any one time, you would add an extra line to the script:
|
'(Declarations)
Dim g_objJobRunner
Set g_objJobRunner = CreateObject("CygNet.API.JobRunner.JobRunner")
g_objJobRunner.SetMaxActiveJobs 3
'End of (Declarations) |
Step 2: Write (or move) your scripts
Write new scripts to be run through the Job Runner in a different location than HSS scripts. Before running existing HSS scripts through Job Runner, they must be moved or changed slightly.
Job Runner scripts can be located in local files, BSS files, or HSS points. For local and BSS files, put the script in a *.VBS file and save it either to the local system (where the HSS has access) or in the BSS. These scripts are executed each time you pass a properly configured Job to the Job Runner.
For HSS points, write the script in the script section of any HyperPoint. There are two differences when writing a script using HSS points for use with the Job Runner:
Step 3: Create Jobs for the Job Runner
Every script to be run using the Job Runner needs a separate Job object to be created and passed to the Job Runner. When this Job object is passed to the Job Runner, the script contained in the Job will be executed when its turn arrives. For example, if a script in a CygNet Studio screen takes a long time to process and Studio becomes non-responsive, Job Runner is another option you can use. After creating, configuring, and submitting a Job object to the Job Runner, use the EventTimer on TheFrame/TheView to periodically check the status of the jobs in the Job Runner. When the jobs are complete, process the output accordingly.
Creating the Job Object
To create a Job, first create the object:
|
Dim objScriptJob
Set objScriptJob = CreateObject("CygNet.API.JobRunner.ScriptJob") |
Specifying the Source Type and Location
After creating the object, specify what type of script source to use and set where that script source can be found. A Job script can come from multiple sources.
An example follows for configuring a job to execute from an HSS point:
|
objScriptJob.ScriptSourceType = 1
objScriptJob.ScriptSourcePath = "CYGNET.HSS:JOBRUNNERTEST1_SCRIPT"
g_objJobRunner.ExecuteJob(objScriptJob) |
To store a unique identifier for the Job and reference it later by asking the Job Runner its status, you can store the result of ExecuteJob() as shown in the example below:
|
objScriptJob.ScriptSourceType = 1
objScriptJob.ScriptSourcePath = "CYGNET.HSS:JOBRUNNERTEST1_SCRIPT"
Dim nJobId
nJobId = g_objJobRunner.ExecuteJob(objScriptJob) |
The following methods are available for interfacing with the JobRunner object:
| Method | Description | Parameters | |
|---|---|---|---|
|
Clears the list of job statuses. Will not stop actively running or queued jobs. Example
|
None |
||
|
Enables or disables more extensive logging to be used when debugging job failures. Example
|
Boolean Enable |
||
|
Submit a job. Returns the Job ID. Example
|
objJob |
||
|
Returns a list of all running jobs. Example
|
None |
||
|
Returns list of all jobs whose statuses JobRunner has stored. Example
|
None |
||
|
Returns the errors associated with a job. Example
|
int JobID |
||
|
Returns the output of a job, mainly used for scripted jobs. Example
|
int JobID |
||
|
Returns the status for a job based on Job ID. Example
|
int JobID |
||
|
Returns a list of all jobs waiting in the queue. Example
|
None |
||
| KillAllScriptJobs |
Terminates all Job Runner script processes. Example
|
||
| KillScriptJob |
Terminates the specified Job ID only. Example
|
int JobID |
|
|
Set an alternate path and/or file name for the Job Runner log file. Example
|
string path string name |
||
|
Set the maximum number of concurrent jobs you want to run. Example
|
int Max |
||
|
Set a temporary download location for BSS-based and point-based script files. Example
|
string path |
||
|
Set the point to which to write job status. Example
|
string point |